﻿using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
//using System.IO;

namespace BCommon
{
    public struct BiniPoint
    {
        public double X;
        public double Y;
        public double Z;
        public double G;
    }

    public struct BiniPoint2D
    {
        public double X;
        public double Z;
        public double G;
    }
    public enum DataSelect
    {
        All,
        Top,
        Bottom,
        Brightest
    }
    class Bini
    {
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string defVal, StringBuilder retVal, int size, string filePath);
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath); 

        [DllImport("kernel32.dll")]
        static extern uint GetTickCount();

        private static string PathName;

        public static void SetPath(string path)
        {
            PathName = path;

        }
        public static void Delay(int dwMs)
        {
 	        int dwStrt = Environment.TickCount;;
	        do
	        {
                Application.DoEvents();
	        }
            while (Math.Abs(Environment.TickCount - dwStrt) < dwMs);
         }

        public static void DelayUint(uint ms)
        {
            uint start = GetTickCount();
            while (GetTickCount() - start < ms)
            {
                Application.DoEvents();

            }
        }
        public static void DelayWatch(uint ms)
        {
            Stopwatch timer = new Stopwatch();
            timer.Restart();
            while (timer.ElapsedMilliseconds < ms)
            {
                Application.DoEvents();
            }
            timer.Stop();

        }

        public static int[] getRandomNum(int num, int minValue, int maxValue)
        {
            Random ra = new Random(unchecked((int)DateTime.Now.Ticks));
            int[] arrNum = new int[num];
            int tmp = 0;
            for (int i = 0; i <= num - 1; i++)
            {
                tmp = ra.Next(minValue, maxValue); //随机取数
                arrNum[i] = getNum(arrNum, tmp, minValue, maxValue, ra); //取出值赋到数组中
            }
            return arrNum;
        }
        public static int getNum(int[] arrNum, int tmp, int minValue, int maxValue, Random ra)
        {
            int n = 0;
            while (n <= arrNum.Length - 1)
            {
                if (arrNum[n] == tmp) //利用循环判断是否有重复
                {
                    tmp = ra.Next(minValue, maxValue); //重新随机获取。
                    getNum(arrNum, tmp, minValue, maxValue, ra);//递归:如果取出来的数字和已取得的数字有重复就重新随机获取。
                }
                n++;
            }
            return tmp;
        }
        public static void SetValue(string section, string key, object value)
        {
            string strPath = GetExePath() + "system.ini";
            string valueS = value.ToString();
            WritePrivateProfileString(section, key, valueS, strPath);
        }

        public static string GetValue(string section, string key)
        {
            StringBuilder sb = new StringBuilder(255);
            string strPath = GetExePath() + "system.ini";
            int i = GetPrivateProfileString(section, key, "", sb, 255, strPath);
            return sb.ToString();
        }
        public static string GetExePath()
        {
            string str = AppDomain.CurrentDomain.BaseDirectory;
            return str;
        }

        public static void ReadExcel(string Pathname)
        {
            //StringBuilder sbr = new StringBuilder();
            //using (FileStream fs = File.OpenRead(Pathname))   //打开myxls.xls文件
            //{
            //    HSSFWorkbook wk = new HSSFWorkbook(fs);   //把xls文件中的数据写入wk中
            //    for (int i = 0; i < wk.NumberOfSheets; i++)  //NumberOfSheets是myxls.xls中总共的表数
            //    {
            //        ISheet sheet = wk.GetSheetAt(i);   //读取当前表数据
            //        for (int j = 0; j <= sheet.LastRowNum; j++)  //LastRowNum 是当前表的总行数
            //        {
            //            IRow row = sheet.GetRow(j);  //读取当前行数据
            //            if (row != null)
            //            {
            //                sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
            //                for (int k = 0; k <= row.LastCellNum; k++)  //LastCellNum 是当前行的总列数
            //                {
            //                    ICell cell = row.GetCell(k);  //当前表格
            //                    if (cell != null)
            //                    {
            //                        sbr.Append(cell.ToString());   //获取表格中的数据并转换为字符串类型
            //                    }
            //                }
            //            }
            //        }
            //    }
            //}
            //sbr.ToString();
            //using (StreamWriter wr = new StreamWriter(new FileStream(@"D:/myText.txt", FileMode.Append)))  //把读取xls文件的数据写入myText.txt文件中
            //{
            //    wr.Write(sbr.ToString());
            //    wr.Flush();
            //}

        }
        public static List<String[]> ReadCSV(string filePathName)
        {
            List<String[]> ls = new List<String[]>();
            StreamReader fileReader = new StreamReader(filePathName);
            string strLine = "";
            while (strLine != null)
            {
                strLine = fileReader.ReadLine();
                if (strLine != null && strLine.Length > 0)
                {
                    ls.Add(strLine.Split(' '));
                    //Debug.WriteLine(strLine);
                }
            }
            fileReader.Close();
            return ls;
        }
        public static void WriteCSV(string filePathName, string[] lsHead, string[] ls)
        {
            bool sts = !File.Exists(filePathName);
            StreamWriter fileWriter = new StreamWriter(filePathName, true, Encoding.Default);
            if (sts)
            {
                foreach (string strArr in lsHead)
                {

                    fileWriter.Write(strArr.ToString() + ",");
                }
                fileWriter.WriteLine(""); 
            }
            foreach (string  strArr in ls)
            {
       
                fileWriter.Write(strArr.ToString() + ",");
            }
            fileWriter.WriteLine("");
            fileWriter.Flush();
            fileWriter.Close();

        }
        public static List<BiniPoint> ReadFile(string filePathName)
        {
            List<BiniPoint> ls = new List<BiniPoint>();
            List<BiniPoint> lsfilter = new List<BiniPoint>();
            BiniPoint PointTemp;
            StreamReader fileReader = new StreamReader(filePathName);
            string strLine = "";
            float dfCompare = 0;
            while (strLine != null)
            {
                strLine = fileReader.ReadLine();
                if (strLine != null && strLine.Length > 0)
                {
                    String[] dest = strLine.Split(',', ':', ';', ' ');
                    if (Math.Abs(dfCompare - float.Parse(dest[1])) > 0.001)
                    {
                        dfCompare = float.Parse(dest[1]);
                        FilterProfile(lsfilter,DataSelect.Bottom, out lsfilter);
                        ls.AddRange(lsfilter);
                        lsfilter.Clear();
                    }
                    PointTemp.X = float.Parse(dest[0]);
                    PointTemp.Y = float.Parse(dest[1]);
                    PointTemp.Z = float.Parse(dest[2]);
                    PointTemp.G = float.Parse(dest[2]);
                    lsfilter.Add(PointTemp);
                    //Debug.WriteLine(strLine);
                }
                
            }
            fileReader.Close();
            return ls;
        }
        public static void FilterProfile(List<BiniPoint> profile, DataSelect layerType, out List<BiniPoint> layer)
        {
            switch (layerType)
            {
                case DataSelect.All:
                    layer = profile;
                    break;

                case DataSelect.Top:
                    layer = profile.OrderBy(p => p.X)
                            .ThenBy(p => p.Z)
                            .GroupBy(p => p.X)
                            .Select(p => p.First())
                            .ToList();
                    break;

                case DataSelect.Bottom:
                    layer = profile.OrderBy(p => p.X)
                            .ThenByDescending(p => p.Z)
                            .GroupBy(p => p.X)
                            .Select(p => p.First())
                            .ToList();
                    break;

                case DataSelect.Brightest:
                    layer = profile.OrderByDescending(p => p.G)
                            .ThenBy(p => p.Z)
                            .GroupBy(p => p.X)
                            .Select(p => p.First())
                            .ToList();
                    break;

                default:
                    throw new ArgumentOutOfRangeException("layerType", layerType, null);
            }
        }

 
    }
}
